package cn.tedu._04mvcweibo.controller;

import cn.tedu._04mvcweibo.common.response.JsonResult;
import cn.tedu._04mvcweibo.common.response.StatusCode;
import cn.tedu._04mvcweibo.mapper.UserMapper;
import cn.tedu._04mvcweibo.pojo.dto.UserLoginDTO;
import cn.tedu._04mvcweibo.pojo.dto.UserRegDTO;
import cn.tedu._04mvcweibo.pojo.entity.User;
import cn.tedu._04mvcweibo.pojo.vo.UserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;


/**
 * 1.Slf4j注解：Lombok注解,添加在类上,会在类中创建一个日志对象log,
 *   通过日志对象log在终端输出对应级别的日志
 * 2.Api注解: Knife4j注解,用于配置在Knife4j页面中显示的模块名
 */
@Api(tags = "01.用户模块")
@Slf4j
@RestController
@RequestMapping("/v1/users/")
public class UserController {
    //自动装配
    @Autowired(required = false)
    private UserMapper userMapper;

    /** 注册功能 */
    /**
     1.RequestBody注解:将JSON格式的数据封装到Java对象
     2.ApiOperation注解:Knife4j注解,用于配置Knife4j页面中显示的方法名
     */
    @ApiOperation(value = "注册功能")
    @PostMapping(value="reg")
    public JsonResult reg(@RequestBody @Validated UserRegDTO userRegDTO){
        /*
            1.确认用户名是否被占用[查询接口方法]
            2.被占用: 直接返回2结束
            3.未被占用: 存入数据表[插入数据接口方法]
                       返回结果 1
         */
        // soutp + 回车
        System.out.println("userRegDTO = " + userRegDTO);
        //是否被占用
        UserVO userVO = userMapper.selectByUsername(userRegDTO.getUsername());
        if (userVO != null){ //被占用
            /*
                1.使用JsonResult统一响应结果;
                2.使用自定义枚举类实现状态码和提示消息的定义;
             */
            return new JsonResult(StatusCode.USERNAME_ALREADY_EXISTS);
        }
        //未被占用
        User user = new User();
        BeanUtils.copyProperties(userRegDTO, user);
        user.setCreated(new Date());
        userMapper.insertUser(user);

        //使用自定义枚举状态码,统一响应数据
        //return new JsonResult(StatusCode.OPERATION_SUCCESS);
        return JsonResult.ok();
    }

    /**
     * 登录功能
     * @param userLoginDTO 数据传输对象
     * @param session 会话保持参数
     * @return int
     * ApiIgnore注解:Knife4j注解,表示让Knife4j忽略此参数,不需要体现在API文档中
     */
    @ApiOperation(value = "登录功能")
    @PostMapping("login")
    public JsonResult login(@RequestBody UserLoginDTO userLoginDTO, @ApiIgnore HttpSession session){
        /*
            通过DEBUG级别的日志输出
            开发阶段：会输出,因为配置文件中设置级别为DEBUG
            上线阶段：不会输出,因为配置文件中设置级别为INFO
         */
        log.debug("userLoginDTO = " + userLoginDTO);

        /*
            1.确认用户名是否正确[调用查询接口]
            2.用户名正确: 校验密码
              2.1 密码正确: 返回1
              2.2 密码错误: 返回2
            3.用户名不正确: 直接返回3
         */
        UserVO userVO = userMapper.selectByUsername(userLoginDTO.getUsername());
        if (userVO == null){//用户名错误
            return new JsonResult(StatusCode.USERNAME_ERROR);
        }
        //校验密码
        if (userVO.getPassword().equals(userLoginDTO.getPassword())){
            //将该用户的标识保存到session会话中
            session.setAttribute("user", userVO);
            //登录成功
            //return new JsonResult(StatusCode.LOGIN_SUCCESS);
            return JsonResult.ok();
        }
        //密码错误
        return new JsonResult(StatusCode.PASSWORD_ERROR);
    }

    /**
     * 获取当前用户功能
     */
    @ApiOperation(value = "获取当前用户功能")
    @GetMapping("currentUser")
    public JsonResult currentUser(@ApiIgnore HttpSession session){
        //从服务器内存中获取当初通过session.setAttribute()存储的用户标识
        UserVO userVO = (UserVO) session.getAttribute("user");

        //通过在JsonResult中添加需要返回数据的构造方法，实现此功能
        //return new JsonResult(StatusCode.OPERATION_SUCCESS, userVO);
        return JsonResult.ok(userVO);
    }

    /**
     * 退出登录功能
     */
    @ApiOperation(value = "退出登录功能")
    @GetMapping("logout")
    public void logout(@ApiIgnore HttpSession session){
        //在服务器内存中删除用户标识
        session.removeAttribute("user");
    }
}








